<?php
/**
 * Zend Framework Extension
 *
 * This script is protected by copyright. It's use, copying, modification
 * and distribution without written consent of the author is prohibited.
 *
 * @category    Zend
 * @package     Zend_View
 * @subpackage  Helpers
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2008 Prospekta Ernest Wagner
 */

/** @see Zend_View_Helper_Abstract */
require_once 'Zend/View/Helper/Abstract.php';

/**
 * Generowanie paginacji według szablonu
 * 
 * @category    Zend
 * @package     Zend_View
 * @subpackage  Helpers
 * @author      Krzysztof Kardasz <krzysztof.kardasz@gmail.com>
 * @copyright   Copyright (c) 2008 Prospekta Ernest Wagner
 */
class Zend_View_Helper_Paginator extends Zend_View_Helper_Abstract
{
    /**
     * Kontener rezultatów
     *
     * @var string
     */
    protected $_container = '<ul class="pagination">%results%</ul>';
    
    /**
     * Szablon pierwszej strona
     *
     * @var string
     */
    protected $_first = '<li><a href="%url%" title="%page%." class="prev">&laquo;</a></li>';
    
    /**
     * Szablon poprzedniej strony
     *
     * @var string
     */
    protected $_prev = '<li><a href="%url%" title="%page%." class="prev">Poprzednie</a></li>';
    
    /**
     * Szablon strony
     *
     * @var string
     */
    protected $_item = '<li><a href="%url%" title="%page%.">%page%</a></li>';
    
    /**
     * Szablon aktualnej strony
     *
     * @var string
     */
    protected $_current = '<li><a href="%url%" title="%page%." class="current">%page%</a></li>';
    
    /**
     * Szablon wielokropku
     *
     * @var string
     */
    protected $_dots = '<li class="paginationDots">&hellip;</li>';
    
    /**
     * Szablon odstępów
     *
     * @var string
     */
    protected $_delimiter = null;
    
    /**
     * Szablon następnej strony
     *
     * @var string
     */
    protected $_next = '<li><a href="%url%" title="%page%." class="next">Następne</a></li>';
    
    /**
     * Szablon ostatniej strony
     *
     * @var string
     */
    protected $_last = '<li><a href="%url%" title="%page%." class="next">&raquo;</a></li>';
    
    /**
     * Zwraca obiekt Paginatora
     *
     * @return Zend_View_Helper_Paginator
     */
    public function paginator ()
    {           
        return $this;
    }
    
    /**
     * Definiowanie szablonu kontenera wyników
     *
     * @param  string $container szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setContainer ($container)
    {   
        $this->_container = $container;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu pierwszej strony
     *
     * @param  string $first szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setFirst ($first)
    {   
        $this->_first = $first;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu poprzedniej strony
     *
     * @param  string $first szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setPrev ($prev)
    {   
        $this->_prev = $prev;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu numeru strony
     *
     * @param  string $item szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setItem ($item)
    {   
        $this->_item = $item;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu aktualnej strony
     *
     * @param  string $current szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setCurrent ($current)
    {   
        $this->_current = $current;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu wielokropka
     *
     * @param  string $dots szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setDots ($dots)
    {   
        $this->_dots = $dots;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu odstępów
     *
     * @param  string $delimiter szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setDelimiter ($delimiter)
    {   
        $this->_delimiter = $delimiter;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu następnej strony
     *
     * @param  string $next szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setNext ($next)
    {   
        $this->_next = $next;        
        return $this;
    }
    
    /**
     * Definiowanie szablonu ostatniej strony
     *
     * @param  string $last szablon
     * @return Zend_View_Helper_Paginator
     */
    public function setLast ($last)
    {   
        $this->_last = $last;        
        return $this;
    }
    
    /**
     * Generuje numery stron prezentowanych wyników
     *
     * @param  integer $page aktualna strona
     * @param  integer $limit limit wyników na stronę
     * @param  integer $total ilość wszystkich wyników
     * @param  array   $params tablica dodatkowych parametrów trasy
     * @param  string  $prefix prefiks do nazwy parametru page (%prefix%page)
     * @param  integer $results ilość prezentowanych numerów stron
     * @return string
     */
    public function pagination ($page = 1, $limit = 1, $total = 1, $params = array(), $prefix = null, $results = 7)
    {   
        if($limit < $total) {
            // total all pages
            $total = ceil($total / $limit);

            // xhtml code
            $xhtml = '';

            if ($total <= $results) {
                // short version of pagination
                for ($i = 1; $i <= $total; $i++) {
                    if($i > 1) {
                        $xhtml .= $this->_template($this->_delimiter, $i, $this->_url($i, $params, $prefix));
                    }
                    if ($i == $page) {
                        $xhtml .= $this->_template($this->_current, $i, $this->_url($i, $params, $prefix));
                    } else {
                        $xhtml .= $this->_template($this->_item, $i, $this->_url($i, $params, $prefix));
                    }
                }
            } else {
                $left = (floor(($results)/2));
                $right = $results-$left-1;
                
                // normal version of pagination
                $min = (($page - $left+1) > 1) ? $page - $left : 1;
                $max = (($page + $right) < $total) ? $page + $right : $total;

                if (($page - $left) <= 1) {
                    $max += ($results - ($max - $min + 1));
                }
                if (($page + $right) >= $total) {
                    $min -= ($results - ($max - $min + 1));
                }

                for ($i = $min; $i <= $max; $i++) {
                    if($i > $min) {
                        $xhtml .= $this->_template($this->_delimiter, $i, $this->_url($i, $params, $prefix));
                    }
                    if ($i == $page) {
                        $xhtml .= $this->_template($this->_current, $i, $this->_url($i, $params, $prefix));
                    } else {
                        $xhtml .= $this->_template($this->_item, $i, $this->_url($i, $params, $prefix));
                    }
                }

                if (($page - $left) > 1) {
                    $xhtml = $this->_template($this->_item, 1, $this->_url(1, $params, $prefix)) . (($min > 1) ? $this->_template($this->_dots) : null) . $xhtml;
                }
                if (($page + $right) < $total) {
                    $xhtml .= ($max < ($total)) ? $this->_template($this->_dots) : null;
                    $xhtml .= $this->_template($this->_item, $total, $this->_url($total, $params, $prefix));
                }
            }

            // create previous link
            if ($page > 1 && $total > 1) {
                $xhtml = $this->_template($this->_prev, ($page-1), $this->_url(($page-1), $params, $prefix)) . $xhtml;
                $xhtml = $this->_template($this->_first, 1, $this->_url(1, $params, $prefix)) . $xhtml;
            }
            // create next link
            if ($page < $total && $total > 1) {
                $xhtml .= $this->_template($this->_next, ($page+1), $this->_url(($page+1), $params, $prefix));
                $xhtml .= $this->_template($this->_last, $total, $this->_url($total, $params, $prefix));
            }

            $xhtml = str_replace('%results%', $xhtml, $this->_container);
            
            return $xhtml;
        }

        return null;
    }
    
    /**
     * Formatowanie szablonu
     *
     * @param  string  $template  szablon
     * @param  integer $page strona
     * @param  string  $url adres url
     * @return string
     */
    protected function _template ($template = null, $page = null, $url = null)
    {   
        return str_replace(array('%page%', '%url%'), array($page, $url), $template);
    }
    
    /**
     * Formatowanie adresu url
     *
     * @param  integer $page strona
     * @param  array   $params tablica dodatkowych parametrów trasy
     * @param  string  $prefix prefiks do nazwy parametru page (%prefix%page)
     * @return string
     */
    protected function _url ($page = null, $params = array(), $prefix = null)
    {   
        return $this->view->url(array_merge ($params, array(($prefix . 'page') => $page)));
    }
}
?>